home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_540 / browser / browserii_src.lzh / Mouse.c < prev    next >
C/C++ Source or Header  |  1991-07-26  |  11KB  |  391 lines

  1. /*
  2.  *    Mouse.c - Copyright © 1991 by S.R. & P.C.
  3.  *
  4.  *    Created:    21 Feb 1991  09:41:20
  5.  *    Modified:    26 Jul 1991  18:14:48
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. #include "Global.h"
  11. #include "Actions.h"
  12. #include "FileList.h"
  13. #include "proto/Mouse.h"
  14. #include "proto/Windows.h"
  15. #include "proto/Scan.h"
  16. #include "proto/Run.h"
  17. #include "proto/Process.h"
  18. #include "proto/Request.h"
  19. #include "proto/Draw.h"
  20. #include "proto/File.h"
  21. #include "proto/FileList.h"
  22.  
  23.  
  24. extern struct BrowserWindow *CurrentWin;
  25. extern struct Screen *Screen;
  26. extern struct Config Config;
  27. extern struct MinList WindowList;
  28. extern char *ReqTitle;
  29. extern short SelectNum;
  30. extern long SelectBytes, SelectBlocks;
  31. extern BPTR BrowserDir;
  32.  
  33. static struct ScrollEntry *LastSelected;
  34. static BOOL SelectDown;        /* Tell if left mouse button is down and if last 
  35.                              * selectdown event made an entry being selected */
  36.  
  37. static short PointerMatrix[36] = {
  38.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3168, 3168,
  39.     2080, 3168, 0, 640, 256, 0, 0, 640, 2080, 3168, 3168, 3168,
  40.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  41. };
  42.  
  43. #define CROSS_XOFFSET    -8L
  44. #define CROSS_YOFFSET    -7L
  45. #define CROSS_SIZE        72L
  46.  
  47.  
  48. /* Open window and scan directory referenced by BPTR DirLock */
  49.  
  50. static void OpenAndScan(struct BrowserWindow *Parent, BPTR DirLock, BPTR RootLock, short Position)
  51. {
  52.     struct BrowserWindow *NewWin;
  53.  
  54.     if (!(NewWin = OpenBrowserWindow(Parent, DirLock, RootLock, Position))) {
  55.         UnLock(DirLock);
  56.         UnLock(RootLock);
  57.         return;
  58.     }
  59.     if (!ScanDir(NewWin))
  60.         CloseBrowserWindow(NewWin);
  61. }
  62.  
  63.  
  64. static BPTR GetRootLock(BPTR DirLock)
  65. {
  66.     char *sptr, buf[REQ_DSIZE];
  67.  
  68.     PathName(DirLock, buf, REQ_DSIZE-1);    /* Work on volume name. May be confusing, sorry */
  69.     sptr = buf;
  70.     while(*sptr && *sptr++ != ':');
  71.     *sptr = '\0';
  72.     return Lock(buf, ACCESS_READ);
  73. }
  74.  
  75.  
  76. /* Name and Type are from the ScrollEntry when not NULL */
  77.  
  78. static void DoDoubleClick(struct BrowserWindow *Win, struct ScrollEntry *S, char *Name, short Type)
  79. {
  80.     BPTR DirLock, RootLock;
  81.     short Position;
  82.  
  83.     if (Type == DLX_FILE) {
  84.         if (DoRun(S, Win->bw_DirLock, Win->bw_RootLock) && !(Config.Options & OPT_KEEPSELECTED))
  85.             DeselectAll(NULL);
  86.     }
  87.     else {
  88.         if (Win->bw_Type == BW_MAIN) {
  89.             if (!(DirLock = Lock(Name, ACCESS_READ))) {
  90.                 SimpleRequest(ReqTitle, "Couldn't access \"%s\"\n%s.", Name, StrIoErr());
  91.                 return;
  92.             }
  93.             if (Type == DLX_ASSIGN) {
  94.                 if(!(RootLock = GetRootLock(DirLock))) {
  95.                     UnLock(DirLock);
  96.                     return;
  97.                 }
  98.             }
  99.             else
  100.                 RootLock = DupLock(DirLock);
  101.             Position = POS_NEWDEV;
  102.         }
  103.         else {
  104.             CurrentDir(Win->bw_DirLock);
  105.             if(!(DirLock = Lock(Name, ACCESS_READ))) {
  106.                 SimpleRequest(ReqTitle, "Couldn't access \"%s\"\n%s.", Name, StrIoErr());
  107.                 CurrentDir(BrowserDir);
  108.                 return;
  109.             }
  110.             CurrentDir(BrowserDir);
  111.             RootLock = DupLock(Win->bw_RootLock);
  112.             Position = POS_SUBDIR;
  113.         }        
  114.         OpenAndScan(Win, DirLock, RootLock, Position);
  115.         DeselectAll(NULL);
  116.     }
  117. }
  118.  
  119.  
  120. void OpenParent(void)
  121. {
  122.     BPTR DirLock, RootLock;
  123.     long err;
  124.  
  125.     if (!(DirLock = ParentDir(CurrentWin->bw_DirLock))) {
  126.         if ((err = IoErr()) != ERROR_DEVICE_NOT_MOUNTED)
  127.             SimpleRequest(ReqTitle, "Couldn't open window\n%s.", (err == 0) ? "No parent dir" : DosError(err));
  128.         return;
  129.     }
  130.     RootLock = DupLock(CurrentWin->bw_RootLock);
  131.     OpenAndScan(CurrentWin, DirLock, RootLock, POS_PARENTDIR);
  132. }
  133.  
  134.  
  135. void OpenDir(void)
  136. {
  137.     struct BrowserWindow *BW;
  138.     static char buf[256];
  139.  
  140.     BW = (struct BrowserWindow *)WindowList.mlh_Head;
  141.     SetWaitPointer(TRUE);
  142.     if (GetString(buf, "Open Dir...", NULL, 40, 255))
  143.         DoDoubleClick(BW, NULL, buf, DLX_ASSIGN);
  144.     SetWaitPointer(FALSE);
  145. }
  146.  
  147.  
  148. void DoSelect(struct BrowserWindow *Win, struct ScrollEntry *S, UBYTE Options)
  149. {
  150.     if (S->se_State & STATE_DELETED)
  151.         return;
  152.     if (S->se_State & STATE_SELECTED) {
  153.         if (Options & OPT_TOGGLESELECT) {
  154.             S->se_State &= ~STATE_SELECTED;
  155.             Win->bw_SelectBytes -= S->se_FileInfo.fi_Size;
  156.             SelectBytes -= S->se_FileInfo.fi_Size;
  157.             Win->bw_SelectBlocks -= S->se_FileInfo.fi_NumBlocks;
  158.             SelectBlocks -= S->se_FileInfo.fi_NumBlocks;
  159.             Win->bw_SelectNum--;
  160.             SelectNum--;
  161.         }
  162.     }
  163.     else {
  164.         S->se_State |= STATE_SELECTED;
  165.         Win->bw_SelectBytes += S->se_FileInfo.fi_Size;
  166.         SelectBytes += S->se_FileInfo.fi_Size;
  167.         Win->bw_SelectBlocks += S->se_FileInfo.fi_NumBlocks;
  168.         SelectBlocks += S->se_FileInfo.fi_NumBlocks;
  169.         Win->bw_SelectNum++;
  170.         SelectNum++;
  171.     }
  172.     LastSelected = S;
  173. }
  174.  
  175.  
  176. static struct ScrollEntry *GetEntryAndPos(struct BrowserWindow *Win, short X, short Y, short *Line, short *Col)
  177. {
  178.     short index, L, C;
  179.  
  180.     if (Y <= 11 || Y >= Win->bw_ScrollStruct.NumLines * 9 + 11)
  181.         return NULL;
  182.     C = (X-4)/Win->bw_ColWidth;
  183.     if (C > Win->bw_NumCol-1)
  184.         return NULL;
  185.     L = (Y-11)/9;
  186.     index = L + Win->bw_ScrollStruct.NumLines*C + Win->bw_ScrollStruct.TopEntryNumber;
  187.     if (index >= Win->bw_ShownEntries)
  188.         return NULL;
  189.     *Line = L;
  190.     *Col = C;
  191.     return Win->bw_EntryArray[index];
  192. }
  193.  
  194.  
  195. void SelectAll(void)
  196. {
  197.     short i;
  198.  
  199.     for( i=0 ; i<CurrentWin->bw_ShownEntries ; i++ )
  200.         DoSelect(CurrentWin, CurrentWin->bw_EntryArray[i], Config.Options);
  201.     RedrawEntries(CurrentWin);
  202.     MakeBottomInfoString(CurrentWin);
  203.     RefreshBottomInfo(CurrentWin);
  204. }
  205.  
  206.  
  207. void SelectMatch(void)
  208. {
  209.     struct ScrollEntry *S;
  210.     short ten, nl, i;
  211.  
  212.     if (CurrentWin->bw_Type == BW_MAIN)
  213.         return;
  214.     SetWaitPointer(TRUE);
  215.     if (FiltersReq(&Config.Select, SELECT_REQ)) {
  216.         ten = CurrentWin->bw_ScrollStruct.TopEntryNumber;
  217.         nl = CurrentWin->bw_ScrollStruct.NumLines;
  218.         for( i=0 ; i<CurrentWin->bw_ShownEntries ; i++ ) {
  219.             S = CurrentWin->bw_EntryArray[i];
  220.             if (MatchFilters(&S->se_FileInfo, &Config.Select)) {
  221.                 DoSelect(CurrentWin, S, Config.Options);
  222.                 if (i >= ten && i < ten + nl * CurrentWin->bw_NumCol)
  223.                     Print(CurrentWin, S, 4+CurrentWin->bw_ColWidth*((i-ten)/nl), 18+((i-ten)%nl)*9);
  224.             }
  225.         }
  226.         MakeBottomInfoString(CurrentWin);
  227.         RefreshBottomInfo(CurrentWin);
  228.     }
  229.     SetWaitPointer(FALSE);
  230. }
  231.  
  232.  
  233. /* Deselect all but Current scrollentry */
  234.  
  235. void DeselectAll(struct ScrollEntry *Current)
  236. {
  237.     struct BrowserWindow *Win;
  238.     struct ScrollEntry *S;
  239.     short i,start,end;
  240.     short x,y;
  241.  
  242.     Config.Select.si_Flags &= ~SI_AFFECT_SUBDIRS;        /* Deselect also files in subdirs */
  243.     Win = (struct BrowserWindow *)WindowList.mlh_Head;
  244.     while(Win->bw_Node.mln_Succ) {
  245.         if (Win->bw_SelectNum > 0) {
  246.             start = Win->bw_ScrollStruct.TopEntryNumber;
  247.             end = MIN(start + Win->bw_NumCol * Win->bw_ScrollStruct.NumLines - 1, Win->bw_ShownEntries-1);
  248.             for( i=0 ; i<Win->bw_ShownEntries ; i++ ) {
  249.                 S = Win->bw_EntryArray[i];
  250.                 if ((S->se_State & STATE_SELECTED) && S != Current) {
  251.                     S->se_State &= ~STATE_SELECTED;
  252.                     Win->bw_SelectBytes -= S->se_FileInfo.fi_Size;
  253.                     SelectBytes -= S->se_FileInfo.fi_Size;
  254.                     Win->bw_SelectBlocks -= S->se_FileInfo.fi_NumBlocks;
  255.                     SelectBlocks -= S->se_FileInfo.fi_NumBlocks;
  256.                     Win->bw_SelectNum--;
  257.                     SelectNum--;
  258.                     if (i < start || i > end)
  259.                         continue;
  260.                     x = 4 + Win->bw_ColWidth * ((i-start)/Win->bw_ScrollStruct.NumLines);
  261.                     y = 18 + 9 * ((i-start) % Win->bw_ScrollStruct.NumLines);
  262.                     Print(Win, S, x, y);
  263.                 }
  264.             }
  265.             MakeBottomInfoString(Win);
  266.             RefreshBottomInfo(Win);
  267.         }
  268.         Win = (struct BrowserWindow *)Win->bw_Node.mln_Succ;
  269.     }
  270. }
  271.  
  272.  
  273. void DoSelectDown(short X, short Y, long Sec, long Mic, USHORT Qual)
  274. {
  275.     static short *ChipPointerMatrix = NULL;
  276.     static ULONG OldSec=0, OldMic=0;
  277.     struct ScrollEntry *S;
  278.     short line, col;
  279.     BOOL ExtendedSelect;
  280.  
  281.     if (!ChipPointerMatrix) {
  282.         ChipPointerMatrix = ArpAllocMem(CROSS_SIZE, MEMF_PUBLIC|MEMF_CHIP);
  283.         CopyMem(PointerMatrix, ChipPointerMatrix, CROSS_SIZE);
  284.     }
  285.     ExtendedSelect = Qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT);
  286.     if (!(S = GetEntryAndPos(CurrentWin, X, Y, &line, &col))) {
  287.         if (!ExtendedSelect)
  288.             DeselectAll(NULL);
  289.         return;
  290.     }
  291.     if (S->se_State & STATE_DELETED)
  292.         return;            /* forbid selection of a deleted entry */
  293.     if ((S->se_State & STATE_SELECTED) && S == LastSelected && DoubleClick(OldSec, OldMic, Sec, Mic)) {
  294.         SetWaitPointer(TRUE);
  295.         DoDoubleClick(CurrentWin, S, S->se_FileInfo.fi_Name, S->se_FileInfo.fi_Type);
  296.         SetWaitPointer(FALSE);
  297.         return;
  298.     }
  299.     OldSec = Sec;
  300.     OldMic = Mic;
  301.     if (!ExtendedSelect)
  302.         DeselectAll(S);
  303.     DoSelect(CurrentWin, S, (Qual & IEQUALIFIER_CONTROL) ? OPT_TOGGLESELECT : Config.Options);
  304.     if (S->se_State & STATE_SELECTED) {
  305.         SetPointer(CurrentWin->bw_Window, ChipPointerMatrix, 16L, 16L, CROSS_XOFFSET, CROSS_YOFFSET);
  306.         SelectDown = TRUE;
  307.     }
  308.     Print(CurrentWin, S, 4+CurrentWin->bw_ColWidth*col, 18+9*line);
  309.     MakeBottomInfoString(CurrentWin);
  310.     RefreshBottomInfo(CurrentWin);
  311. }
  312.  
  313.  
  314. void DoSelectUp(short X, short Y)
  315. {
  316.     struct BrowserWindow *Win;
  317.     struct ScrollEntry *S;
  318.     struct Window *W;
  319.     struct Layer *Layer;
  320.     struct HeadFileList *hfl;
  321.     BPTR Dest, DestRoot = NULL;
  322.     char buf[REQ_DSIZE];
  323.     short sx,sy,l,c;    /* l & c not used. Just needed by GetEntryAndPos() */
  324.  
  325.     if (!SelectDown)    /* Handle selectup only if something has just been selected */
  326.         return;
  327.     SelectDown = FALSE;
  328.     W = CurrentWin->bw_Window;
  329.     ClearPointer(W);
  330.     sx = X+W->LeftEdge;
  331.     sy = Y+W->TopEdge;
  332.     LockLayerInfo(&Screen->LayerInfo);
  333.     Layer = WhichLayer(&Screen->LayerInfo, sx, sy);
  334.     UnlockLayerInfo(&Screen->LayerInfo);
  335.     if (Layer && (W = (struct Window *)Layer->Window)) {
  336.         if (!(Win = FindWindow(W))) {
  337.             SimpleRequest(ReqTitle, "Can't move files into this window.");
  338.             return;
  339.         }
  340.         S = GetEntryAndPos(Win, sx - W->LeftEdge, sy - W->TopEdge, &l, &c);
  341.         if (SelectNum && (!S || !(S->se_State & STATE_SELECTED)) && S != LastSelected) {
  342.             if (Win == CurrentWin && (!(Config.Options & OPT_MOVEINTOSUB) || !S || S->se_FileInfo.fi_Type == DLX_FILE))
  343.                 return;
  344.             /* now, we know there's something to do */
  345.             if (!S || S->se_FileInfo.fi_Type == DLX_FILE || !(Config.Options & OPT_MOVEINTOSUB)) {
  346.                 /* Not over an object, nor a file, or over a dir but not move into subs */
  347.                 if (Win->bw_Type == BW_MAIN && !(Config.Options & OPT_MOVEINTOSUB))
  348.                     SimpleRequest(ReqTitle, "Can't move files into this window.");
  349.                 else if (hfl = MakeSelectedList(Win, DupLock(Win->bw_DirLock), DupLock(Win->bw_RootLock)))
  350.                     RunAction(hfl, BROWSERACTION_COPYMOVE);
  351.             }
  352.             else {
  353.                 /* dest is a dir which was visible in the BrowserWindow, move into sub is allowed */
  354.                 if (Config.Options & OPT_ASKBEFOREMOVE) {
  355.                     if (Win->bw_Type == BW_DIR) {
  356.                         strcpy(buf, (char *)Win->bw_Window->Title);
  357.                         TackOn(buf, S->se_FileInfo.fi_Name);
  358.                     }
  359.                     else
  360.                         strcpy(buf, S->se_FileInfo.fi_Name);
  361.                     if (!TwoGadRequest(ReqTitle, "Really move files into\n\"%s\" ?", buf))
  362.                         return;
  363.                 }
  364.                 if (Win->bw_Type == BW_DIR) {
  365.                     CurrentDir(Win->bw_DirLock);
  366.                     if (Dest = Lock(S->se_FileInfo.fi_Name, ACCESS_READ))
  367.                         DestRoot = DupLock(Win->bw_RootLock);
  368.                     CurrentDir(BrowserDir);
  369.                 }
  370.                 else {
  371.                     /* it is a volume, device, or assign, so no parent dir */
  372.                     if (Dest = Lock(S->se_FileInfo.fi_Name, ACCESS_READ)) {
  373.                         if (S->se_FileInfo.fi_Type == DLX_ASSIGN) {
  374.                             if (!(DestRoot = GetRootLock(Dest))) {
  375.                                 UnLock(Dest);
  376.                                 return;
  377.                             }
  378.                         }
  379.                         else    /* volume or device */
  380.                             DestRoot = DupLock(Dest);
  381.                     }
  382.                 }
  383.                 if (Dest && (hfl = MakeSelectedList(FindDir(Dest), Dest, DestRoot)))
  384.                     RunAction(hfl, BROWSERACTION_COPYMOVE);
  385.             }
  386.         }
  387.     }
  388. }
  389.  
  390.  
  391.